package com.anti.jdbc.core.storeprocedure;

import com.anti.jdbc.support.SpSupportBean;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Description TODO
 * @Author anTi
 * @Date 2020-10-6
 */
public class SpBeanParamterBuilder {
    private static final Map<Class<?>, SpBeanParamters> cache = new HashMap();
    public static List<Field> getDeclaredFields(Class<?> beanType) {
        List<Field> list = new ArrayList();
        Field[] arr$ = beanType.getDeclaredFields();
        int len$ = arr$.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            Field field = arr$[i$];
            if (field.getAnnotation(SpIn.class) != null || field.getAnnotation(SpOut.class) != null || field.getAnnotation(SpInOut.class) != null) {
                list.add(field);
            }
        }

        Class parentClass = beanType.getSuperclass();
        if (parentClass != null && !parentClass.getName().toLowerCase().equals("java.lang.object")) {
            List<Field> parentFields = getDeclaredFields(parentClass);
            list.addAll(parentFields);
        }

        return list;
    }
    public static SpBeanParamters build(Class<? extends SpSupportBean> beanType) {
        if (cache.containsKey(beanType)) {
            return (SpBeanParamters)cache.get(beanType);
        } else {
            synchronized(cache) {
                List<Field> fields = getDeclaredFields(beanType);
                int size = fields.size();
                SpBeanParamter[] paramters = new SpBeanParamter[size + 1];
                int index = 0;
                int maxIndex = 0;
                Iterator i$ = fields.iterator();

                while(i$.hasNext()) {
                    Field field = (Field)i$.next();
                    SpBeanParamter spBeanParamter = null;
                    SpIn spIn = (SpIn)field.getAnnotation(SpIn.class);
                    if (spIn != null) {
                        index = spIn.value();
                        spBeanParamter = new SpBeanParamter(field.getName(), field.getType(), ParamInOut.IN);
                    } else {
                        SpOut spOut = (SpOut)field.getAnnotation(SpOut.class);
                        if (spOut != null) {
                            index = spOut.value();
                            spBeanParamter = new SpBeanParamter(field.getName(), field.getType(), ParamInOut.OUT);
                        } else {
                            SpInOut spInOut = (SpInOut)field.getAnnotation(SpInOut.class);
                            if (spInOut != null) {
                                index = spInOut.value();
                                spBeanParamter = new SpBeanParamter(field.getName(), field.getType(), ParamInOut.INOUT);
                            }
                        }
                    }

                    if (spBeanParamter != null) {
                        if (maxIndex < index) {
                            maxIndex = index;
                        }

                        paramters[index] = spBeanParamter;
                    }
                }

                SpBeanParamters spBeanParamters = new SpBeanParamters(paramters, maxIndex);
                cache.put(beanType, spBeanParamters);
                return spBeanParamters;
            }
        }
    }
}
